package com.pin.si.www.framework.config.thread;

import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.task.support.TaskExecutorAdapter;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

/**
 * 虚拟线程配置类
 * <p>
 * 配置应用程序使用 Java 21 的虚拟线程特性，提高并发性能。
 * </p>
 * <p>
 * 注意：需要 Java 21 或更高版本支持
 * </p>
 */
@Configuration(proxyBeanMethods = false)
@EnableAsync // 启用异步任务
@EnableScheduling // 启用定时任务
public class VirtualThreadConfig {

    /**
     * 提供虚拟线程执行器
     * 用于执行异步任务，提高并发性能
     * shutdown() 方法用于销毁虚拟线程等待完成任务并正确释放资源
     */
    @Bean(destroyMethod = "shutdown")
    public ExecutorService virtualThreadExecutor() {
        return Executors.newVirtualThreadPerTaskExecutor();
    }

    /**
     * 配置虚拟线程的 Tomcat 执行器（核心配置）
     * 使 HTTP 请求在虚拟线程中处理
     */
    @Bean
    public TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() {
        return protocolHandler -> {
            // 创建虚拟线程工厂
            ThreadFactory virtualThreadFactory = Thread.ofVirtual()
                    .name("vt-tomcat-", 0)  // 线程名前缀和计数器
                    .factory();

            // 配置 Tomcat 使用虚拟线程执行器
            protocolHandler.setExecutor(Executors.newThreadPerTaskExecutor(virtualThreadFactory));
        };
    }

    /**
     * 配置异步任务执行器使用虚拟线程
     * 替换默认的异步执行器
     */
    @Bean(name = {
            "taskExecutor",
            TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME
    })
    public AsyncTaskExecutor asyncTaskExecutor() {
        // 创建虚拟线程工厂
        ThreadFactory virtualThreadFactory = Thread.ofVirtual()
                .name("vt-async-", 0)  // 异步线程名前缀
                .factory();

        // 创建基于虚拟线程的任务执行器
        return new TaskExecutorAdapter(Executors.newThreadPerTaskExecutor(virtualThreadFactory));
    }

    /**
     * 配置调度任务执行器使用虚拟线程
     * 用于 @Scheduled 注解的定时任务
     * 示例：@Scheduled(scheduler = "virtualThreadTaskScheduler", fixedRate = 1000)
     * 覆盖 Spring 默认定时器的调度执行器：@Bean(name = "taskScheduler") + spring.main.allow-bean-definition-overriding=true
     */
    @Bean(name = "taskScheduler")
    public TaskScheduler virtualThreadTaskScheduler() {
        // 创建虚拟线程工厂
        ThreadFactory virtualThreadFactory = Thread.ofVirtual()
                .name("vt-scheduler-", 0)  // 调度线程名前缀
                .factory();

        // 创建基于虚拟线程的调度器
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setThreadFactory(virtualThreadFactory);
        scheduler.setPoolSize(100); // 池大小
        return scheduler;
    }

}
